/*
	Stargate SENT for GarrysMod10
	Copyright (C) 2007  aVoN

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
-- FIXME: Todo - Rewrite this using "ANIM" like in "stargate_iris" sent.
ENT.Sequence = {};

--################# Pegasus gates - Dialling sequence @aVoN
-- ATTENTION: The dialling time takes exactly 7 seconds with my gates (dialled in fast mode). When you code your own gates, make them take 7 seconds too!
-- You can check a dialling sequence's length with adding "print_r(delay)" to end of the stargate_base's ENT:RunAction() function
function ENT.Sequence:Dial(inbound,fast,fail,busy)
	local action = self:New();
	
	local snd = self.Sounds.Chevron;
	local chev = 1
	
	for i = 1,9 do
	
		local ct = { 1, 2, 3, 8, 9, 4, 5, 6, 7 }
		local chev = ct[i]
		
		for k=1,9 do
		
			local l = math.random(1,36);
		
			action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.OnButtonLock,80,math.random(50,150)},d=0});
			action:Add({f=self.RingLight,v={self,l,false},d=0.2});
			
		end
		
		if(i == 9) then
			
			action:Add({f=self.RingLight,v={self,36,true},d=0.1});
			
			action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.Lock,90,math.random(98,103)},d=0.5});
			action:Add({f=self.ActivateChevron,v={self,7,true,true},d=1});
			
			action:Add({f=self.Open,v={self},d=0});
		
		else
		
		
			action:Add({f=self.ActivateChevron,v={self,7,true,true},d=0});
			action:Add({f=self.EmitSound,v={self.Entity,snd,90,math.random(98,103)},d=0.5});
			action:Add({f=self.ActivateChevron,v={self,7,false,true},d=0});
			
			action:Add({f=self.EmitSound,v={self.Entity,snd,90,math.random(98,103)},d=0.1});
			action:Add({f=self.ActivateChevron,v={self,chev,true,true},d=0.9});
		
		end
	
	end
	
	return action;
end

--################# DialFail sequence @aVoN
function ENT.Sequence:DialFail(instant_stop,play_sound)
	local action = self:New();
	local delay = 1.5;
	if(instant_stop) then delay = 0 end;
	action:Add({f=self.SetStatus,v={self,false,true,true},d=0}); -- We need to keep in "dialling" mode to get around with conflicts
	if(self.Entity.Active or play_sound) then
	    action:Add({f=self.RingSound,v={self,false},d=0});
		action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.Fail,90,math.random(95,105)},d=0});-- Fail sound
	end
	action:Add({f=self.SetShutdown,v={self,true},d=0});
	action:Add({f=self.DHDDisable,v={self,1.5,true},d=delay});-- Shutdown EVERY DHD

	-- Stop all chevrons (if active only!)
	if(self.Entity.Active or play_sound) then
		--if (self.Entity:GetClass() == "stargate_supergate") then
		--	action:Add({f=self.DisActivateLights,v={self,true},d=0});
		--end

		action:Add({f=self.ActivateRing,v={self,false},d=0});

		for i=1,9 do
			action:Add({f=self.ActivateChevron,v={self,i,false},d=0});
		end
	end
	if(self.Shutdown) then
		action:Add({f=self.Shutdown,v={self,true,self.Entity.Active or play_sound},d=0});
	end
	if self.Entity:GetClass() == "stargate_supergate" then
		action:Add({f=self.DisActivateLights,v={self},d=0});
	end
	action:Add({f=self.SetWire,v={self,"Dialing Address",""},d=0}); -- Wire
	action:Add({f=self.SetWire,v={self,"Dialing Symbol",""},d=0}); -- Wire
	action:Add({f=self.SetWire,v={self,"Dialed Symbol",""},d=0}); -- Wire
	action:Add({f=self.SetWire,v={self,"Chevron Locked",0},d=0}); -- Wire
	action:Add({f=self.SetChevrons,v={self,0,0},d=0}); -- Wire
	action:Add({f=self.SetStatus,v={self,false,false},d=0.8}); -- Make the Wire-Value of "-7" = dial-fail stay longer so people's script work along with the sound
	action:Add({f=self.SetWire,v={self,"Chevron",0},d=0}); -- Wire
	action:Add({f=self.SetShutdown,v={self,false},d=0});
	return action;
end

--################# Instantly open sequence for new slow dial and on button press by AlexALX
function ENT.Sequence:InstantOpen(action,delay,instant,inbound,slow,nox,fail)
	if (not action) then
		action = self:New();
	end
	if (instant) then
		action:Add({f=self.SetStatus,v={self,false,true,false,true},d=0});
	end
	local chevs = 7;
	local count = #self.DialledAddress
	if (inbound and IsValid(self.Target) and self.Target.IsStargate) then
		count = #self.Target.DialledAddress
	end
	chevs = 7
	if (count >= 8 and count <= 10) then
		chevs = count-1;
	end
	for i=1,9 do
		action:Add({f=self.ActivateChevron,v={self,i,false,true},d=0});
	end
	action:Add({f=self.SetChevrons,v={self,0,0},d=0}); -- Wire
	action:Add({f=self.RingSound,v={self,false},d=0});
	action:Add({f=self.RingLight,v={self,0,true,true},d=0});
	action:Add({f=self.RingLight,v={self,0,false,true},d=0});
	action:Add({f=self.Fire,v={self,"SetBodyGroup",0,0.05},d=0});
	for i=1,chevs do
		local b = i+1;
		if (i == 8) then
			b = 11
		elseif (i == 9) then
			b = 12
		end
		action:Add({f=self.ActivateChevron,v={self,i,true,inbound,b},d=0});
		action:Add({f=self.DHDSetChevron,v={self,i},d=0});
	end
	if (inbound) then
		action:Add({f=self.RingLight,v={self,36,true},d=0});
	end
	local dialaddress = "";
	for i=1,chevs do
		if (self.DialledAddress[i] != nil) then
			dialaddress = dialaddress..tostring(self.DialledAddress[i]);
		end
	end
	action:Add({f=self.SetChevrons,v={self,chevs,1,true},d=0}); -- Wire
	action:Add({f=self.SetWire,v={self,"Dialing Address",dialaddress},d=0}); -- Wire
	action:Add({f=self.SetWire,v={self,"Dialing Symbol",""},d=0}); -- Wire
	if (not fail) then
		action:Add({f=self.SetWire,v={self,"Chevron",chevs},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Chevron Locked",1},d=0}); -- Wire
	else
		action:Add({f=self.SetWire,v={self,"Chevron",-chevs},d=0}); -- Wire
	end
	if (inbound) then
		action:Add({f=self.SetWire,v={self,"Inbound",1},d=0});
	end
	if (nox or not inbound) then
		action:Add({f=self.FakeDelay,v={self},d=delay});
	else
		action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.LockInbound,90,math.random(98,103)},d=delay});
	end
	return action;
end

--################# On Button Chevron Press Feature @Madman07, Edited by AlexALX

function ENT.Sequence:OnButtonDialFail(chev,only_chev_wire,busy)
	local action = self:New();
	if (busy) then
		--action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.OnButtonLock,90,math.random(98,103)},d=1.0});
		action:Add({f=self.FakeDelay,v={self.Entity},d=1.0});
	end
	if (not only_chev_wire) then
		for i=1,9 do
			action:Add({f=self.ActivateChevron,v={self,i,false},d=0});
		end
		action:Add({f=self.ActivateChevron,v={self,1,false},d=0.1});
		action:Add({f=self.Shutdown,v={self},d=0});
		action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.Fail,90,math.random(98,103)},d=0});
		action:Add({f=self.SetWire,v={self,"Dialing Address",""},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Dialed Symbol",""},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Dialing Symbol",""},d=0}); -- Wire
	end
	action:Add({f=self.SetWire,v={self,"Chevron",-chev},d=0}); -- Wire
	return action;
end

function ENT.Sequence:OnButtonChevron(lightup, dialchev, address, symbol, fail, busy, slow)
	local action = self:New();
	local dialaddress = "";
	local dialsymbol = "";
	for i=1,dialchev do
		if (address[i] != nil) then
			dialaddress = dialaddress..tostring(address[i]);
			if (i == dialchev) then
				dialsymbol = tostring(address[i]);
			end
		end
	end
	if (dialchev >= 1) then
		action:Add({f=self.SetStatus,v={self,false,false,false,true,true},d=0});
	else
		action:Add({f=self.SetStatus,v={self,false,false,false,false},d=0});
	end

 	local actdialchev = dialchev
	if (not lightup) then actdialchev = actdialchev+1 end
	if (symbol != "#" and actdialchev!=9) then
		if (actdialchev==7 or actdialchev==8) then
			actdialchev = actdialchev+1;
		end
	else
		actdialchev = 7
	end

	local b = dialchev+1;

	if (dialchev == 7 and symbol != "#") then
		b = 9
	elseif (dialchev == 8 and symbol != "#") then
		b = 10
	elseif (dialchev == 8 and symbol == "#") then
		b = 11
	elseif (dialchev == 9) then
		b = 12
	end

	if (not lightup) then
		if (dialchev == 7 and symbol == "#") then
			b = 9
		elseif (dialchev == 8) then
			b = 10
		end
	end

	if lightup then
		local dir = (-1)^(dialchev); -- Direction, into the moving chevrons goes
		local rounds = 16;
		local spintime = 0.05;
		if(slow)then
			spintime = 0.06;
			rounds = 32;
		end
		local snd = self.Sounds.Chevron2;
		local chev = self.ChevronLocksb[actdialchev]-rounds*dir; -- where are we starting?
		action:Add({f=self.RingLight,v={self,0,true,true},d=0});
		action:Add({f=self.RingLight,v={self,0,false,true},d=0});
		action:Add({f=self.SetWire,v={self,"Dialing Symbol",dialsymbol},d=0}); -- Wire
		--action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.Ring,90,math.random(98,103)},d=0}); -- Ring Sound
		if (slow) then action:Add({f=self.RingSound,v={self,true},d=0}); end
		for i=1,rounds do
			chev = chev+dir;
			action:Add({f=self.RingLight,v={self,chev},d=spintime});
		end
		action:Add({f=self.RingSound,v={self,false},d=0});
		if (actdialchev != 7 or not fail) then
			action:Add({f=self.EmitSound,v={self.Entity,snd,90,math.random(98,103)},d=0});
		end
		if (not fail or busy) then
			action:Add({f=self.ActivateChevron,v={self,actdialchev,true,false,b},d=0}); -- Chevron lights up
			action:Add({f=self.SetChevrons,v={self,actdialchev,1},d=0}); -- Wire
			action:Add({f=self.SetWire,v={self,"Chevron",dialchev},d=0}); -- Wire
		elseif (fail) then
			action:Add({f=self.RingLight,v={self,0,true,true},d=0});
			action:Add({f=self.RingLight,v={self,0,false,true},d=0});
			action:Add({f=self.SetWire,v={self,"Chevron",-dialchev},d=0}); -- Wire
		end
		action:Add({f=self.SetWire,v={self,"Dialing Address",dialaddress},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Dialed Symbol",dialsymbol},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Dialing Symbol",""},d=0}); -- Wire

		if (actdialchev == 7) then
			if (not fail) then
				action:Add({f=self.SetWire,v={self,"Chevron Locked",1},d=0}); -- Wire
			else
				local delay = 2.0
				if (busy) then delay = 1.5 end
				action:Add({f=self.EmitSound,v={self.Entity,snd,90,math.random(98,103)},d=delay});
			end
		end
	else
		--local snd = self.Sounds.Chevron2;
		--action:Add({f=self.EmitSound,v={self.Entity,snd,90,math.random(98,103)},d=0});
		action:Add({f=self.StopActions,v={self},d=0});
		action:Add({f=self.RingLight,v={self,0,true,true},d=0});
		action:Add({f=self.RingLight,v={self,0,false,true},d=0});

		action:Add({f=self.ActivateChevron,v={self,actdialchev,false,false,b},d=0}); -- Chevron lights down
		action:Add({f=self.SetChevrons,v={self,actdialchev,0},d=0}); -- Wire

		action:Add({f=self.SetWire,v={self,"Chevron",dialchev},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Dialing Address",dialaddress},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Dialed Symbol",dialsymbol},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Dialing Symbol",""},d=0}); -- Wire
		action:Add({f=self.SetWire,v={self,"Chevron Locked",0},d=0}); -- Wire
	end
	return action;
end